﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using DevExpress.AgDataGrid;

namespace Test.Silverlight.DataGrid
{
    public partial class MainPage : UserControl, IDemoItemOwner
    {
        bool IsDemoInitialized { get; set; }
        bool IsOptionsPanelCollapsed { get; set; }
        FrameworkElement noOptionsElement;
        FrameworkElement NoOptionsElement
        {
            get
            {
                if (noOptionsElement == null)
                {
                    noOptionsElement = (FrameworkElement)NoOptionsTemplate.LoadContent();
                }
                return noOptionsElement;
            }
        }
        bool IsDescriptionPanelVisible { get { return DescriptionPanel.Opacity > 0; } }
        List<Button> expandDescriptionButtons;
        List<Button> ExpandDescriptionButtons
        {
            get
            {
                if (expandDescriptionButtons == null)
                    expandDescriptionButtons = new List<Button>();
                return expandDescriptionButtons;
            }
        }

        public MainPage()
        {
            InitializeComponent();
            Width = double.NaN;
            Height = double.NaN;
            DemosList.AddItem("General", "Get data from web service", typeof (General), this);
            DemosList.AddItem("Column Types", @"Multiple pre-defined column types ship with the AgDataGrid Suite, including text, date, Boolean, and image column. 
To enter data edit mode, use one of the following
1) Double click a data cell.
2) Click the focused data cell.
3) Press F2 or the ENTER key.
Templates can be used to customize the appearance of a column’s individual cells and define a custom editor for a given column. This approach is demonstrated for the Salary column.", typeof(ColumnTypes), this);
            DemosList.AddItem("Grouping", "Grouping against multiple columns is supported. To group data by a specific column, drag its header onto the group panel. Drag column headers within the group panel to change the order of grouping columns.\nTo expand/collapse a group row, use any of the following: double-click a group row, click a group row's expand arrow, press the Right/Left arrow key.", typeof(Grouping), this);
            DemosList.AddItem("Preview", "An animated preview panel is available for each data row.\nThe preview panel is capable of displaying either a certain data field's value or any custom content defined using a DataTemplate.\nIn this demo, preview panels contain price and memo information, and an image (move the mouse over an image to enlarge it).", typeof(Preview), this);
            DemosList.AddItem("Preview Display Mode", "The following positioning options are available for preview panels:\n- Below the focused data row (Normal);\n- In a popup window invoked when the mouse hovers over a data row (ToolTip);\n- Outside the grid control (Outside).", typeof(PreviewLayout), this);
            DemosList.AddItem("Total Summaries", "Different predefined types of total summaries can be automatically calculated for columns and displayed within appropriate column footers.\nYou can also handle specific events to calculate custom summaries. To see this feature in action, check the Custom button and select multiple rows.", typeof(TotalSummaries), this);
            DemosList.AddItem("Column Layout", "Column widths can be automatically modified so that their total width matches the grid's width (check the Column Auto Width box).\nIn this demo, each column's layout can be customized using the following options:\n[F] Fixed Width - specifies whether a column's width remains the same when the Column Auto Width feature is enabled;\n[S] Allow Sizing - controls the ability to resize a column using the mouse.\n[W] Text Wrapping - enables auto content wrapping for column cell texts.", typeof(ColumnsLayout), this);
            DemosList.AddItem("Row Template", @"The appearance of individual grid elements (such as column headers, data and summary cells) can be fully customized via Templates.
In this demo, a DataTemplate is used to define data row layout.", typeof(RowTemplate), this);
            DemosList.AddItem("Customization", "You can change visibility of grid panels thus exposing or disabling particular end-user interaction features.\nTo enhance grid readability, you can apply a custom style for alternating rows.", typeof(Customization), this);
            lbDemosList.ItemsSource = DemosList.Demos;
            lbDemosList.LayoutUpdated += lbDemosList_LayoutUpdated;
        }

        void lbDemosList_LayoutUpdated(object sender, EventArgs e)
        {
            if (!IsDemoInitialized) InitDemoListBox();
        }

        void InitDemoListBox()
        {
            if (lbDemosList.Items.Count > 0)
            {
                lbDemosList.SelectedIndex = 0;
            }
            IsDemoInitialized = true;
        }

        DemoItem SelectedDemoItem { get { return lbDemosList.SelectedItem as DemoItem; } }
        void OnSelectedDemoChanged()
        {
            if (SelectedDemoItem == null)
            {
                mainContent.Content = null;
            }
            else
            {
                tbDemoName.Text = SelectedDemoItem.ToString();
                mainContent.Content = SelectedDemoItem.ContentElement;
                if (XAMLButton.IsChecked == true)
                {
                    XAMLContent.Content = SelectedDemoItem.XAMLBlock;
                }
                if (CSButton.IsChecked == true)
                {
                    CSContent.Content = SelectedDemoItem.CSBlock;
                }
                if (SelectedDemoItem.OptionsElement == null)
                {
                    CollapseExpandOptionsButton.Visibility = Visibility.Collapsed;
                    if (OptionsPanel.Child != NoOptionsElement)
                    {
                        OptionsPanel.Child = NoOptionsElement;
                    }
                    if (!IsOptionsPanelCollapsed) ChangeOptionsPanelCollapsed();
                }
                else
                {
                    CollapseExpandOptionsButton.Visibility = Visibility.Visible;
                    OptionsPanel.Child = UpdateOptionsElementStyle(SelectedDemoItem.OptionsElement);
                    if (IsOptionsPanelCollapsed) ChangeOptionsPanelCollapsed();
                }
                OptionsPanel.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
                OptionsPanelContainerShowAnimationKeyFrame.Value = OptionsPanel.DesiredSize.Height;
                if (OptionsPanelContainer.Height > 0)
                    OptionsPanelContainer.Height = OptionsPanel.DesiredSize.Height;
                DescriptionPanelText.Text = SelectedDemoItem.Description;
            }
            Button button = null;
            if (lbDemosList.SelectedIndex >= 0 && lbDemosList.SelectedIndex < ExpandDescriptionButtons.Count)
                button = ExpandDescriptionButtons[lbDemosList.SelectedIndex];
            if (IsDescriptionPanelVisible)
                OpenDescriptionPanel(button);
            else
                CloseDescriptionPanel(button);
        }
        void MainPage_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Button button = null;
            if (lbDemosList.SelectedIndex >= 0 && lbDemosList.SelectedIndex < ExpandDescriptionButtons.Count)
                button = ExpandDescriptionButtons[lbDemosList.SelectedIndex];
            CloseDescriptionPanel(button);
        }
        Panel UpdateOptionsElementStyle(Panel optionsPanel)
        {
            if (optionsPanel == null) return optionsPanel;
            foreach (UIElement child in optionsPanel.Children)
            {
                UpdateOptionsElementStyle(child as Panel);
                UpdateTextBlockStyle(child);
                UpdateRadioButtonStyle(child);
                UpdateCheckBoxStyle(child);
                UpdateContentControlStyle(child);
                UpdateButtonStyle(child);
            }
            return optionsPanel;
        }
        void UpdateTextBlockStyle(UIElement element)
        {
            TextBlock textBlock = element as TextBlock;
            if (textBlock == null || textBlock.Style != null) return;
            textBlock.Style = DefaultTextBlockStyle;
        }
        void UpdateRadioButtonStyle(UIElement element)
        {
            RadioButton rb = element as RadioButton;
            if (rb == null || rb.Style != null) return;
            rb.Style = DefaultRadioButtonStyle;
        }
        void UpdateCheckBoxStyle(UIElement element)
        {
            CheckBox rb = element as CheckBox;
            if (rb == null || rb.Style != null) return;
            rb.Style = dxElementStyles.GetStyle("CheckBoxStyle");
        }
        void UpdateButtonStyle(UIElement element)
        {
            Button rb = element as Button;
            if (rb == null || rb.Style != null) return;
            rb.Style = DefaultButtonStyle;
        }
        void UpdateContentControlStyle(UIElement element)
        {
            ContentControl control = element as ContentControl;
            if (control == null) return;
            UpdateTextBlockStyle(control.Content as UIElement);
        }
        void lbDemosList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            OnSelectedDemoChanged();
        }

        void ExpandDescriptionButton_Click(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;
            if (button == null) return;
            if (IsDescriptionPanelVisible)
            {
                CloseDescriptionPanel(button);
            }
            else
                OpenDescriptionPanel(button);
        }
        void OpenDescriptionPanel(Button button)
        {
            FrameworkElement parent = FindButtonRoot(button);
            Point location = parent.TransformToVisual(DescriptionPanelContainer).Transform(new Point(parent.ActualWidth, 0));
            DescriptionPanelTranslateTransform.X = location.X;
            DescriptionPanelTranslateTransform.Y = ExpandDescriptionButtons.IndexOf(button) * 36;
            DescriptionPanelShowAnimation.Begin();

            if (button != null)
            {
                Storyboard buttonShowAnimation = (Storyboard)button.Resources["ExpandDescriptionButtonShowAnimation"];
                if (buttonShowAnimation != null)
                    buttonShowAnimation.Begin();
            }
        }
        void CloseDescriptionPanel(Button button)
        {
            DescriptionPanelHideAnimation.Begin();
            if (button != null)
            {
                Storyboard buttonHideAnimation = (Storyboard)button.Resources["ExpandDescriptionButtonHideAnimation"];
                if (buttonHideAnimation != null)
                    buttonHideAnimation.Begin();
            }
        }
        FrameworkElement FindButtonRoot(Button button)
        {
            FrameworkElement parent = VisualTreeHelper.GetParent(button) as FrameworkElement;
            while (parent != null && parent.Name != "RootElement")
            {
                parent = VisualTreeHelper.GetParent(parent) as FrameworkElement;
            }
            return parent;
        }
        void CollapseExpandOptionsButton_Click(object sender, RoutedEventArgs e)
        {
            ChangeOptionsPanelCollapsed();
        }

        void ChangeOptionsPanelCollapsed()
        {
            if (!IsOptionsPanelCollapsed)
                CollapseOptionsStory.Begin();
            else
                ExpandOptionsStory.Begin();
            IsOptionsPanelCollapsed = !IsOptionsPanelCollapsed;
        }

        void ExpandDescriptionButton_Loaded(object sender, RoutedEventArgs e)
        {
            ExpandDescriptionButtons.Add((Button)sender);
            if (!IsDescriptionPanelVisible && ExpandDescriptionButtons.Count == 1)
                OpenDescriptionPanel((Button)sender);
        }

        void ExpandDescriptionButton_MouseEnter(object sender, MouseEventArgs e)
        {
            Button button = (Button)sender;
            Storyboard anim = (Storyboard)button.Resources["ExpandDescriptionButtonMouseOverAnimation"];
            anim.Begin();
        }

        void ExpandDescriptionButton_MouseLeave(object sender, MouseEventArgs e)
        {
            Button button = (Button)sender;
            Storyboard anim = (Storyboard)button.Resources["ExpandDescriptionButtonNormalAnimation"];
            anim.Begin();
        }
        private void XAMLButton_Click(object sender, RoutedEventArgs e)
        {
            XAMLContent.Content = SelectedDemoItem.XAMLBlock;
            XAMLContent.Visibility = Visibility.Visible;
            CSContent.Visibility = Visibility.Collapsed;
        }
        private void CodeButton_Click(object sender, RoutedEventArgs e)
        {
            if (XAMLContent == null) return;
            XAMLContent.Visibility = Visibility.Collapsed;
            CSContent.Visibility = Visibility.Collapsed;
        }

        #region IDemoItemOwner members
        Style IDemoItemOwner.ScrollViewerStyle { get { return dxElementStyles.GetStyle("ScrollViewerStyle"); } }
        #endregion

        private void CSButton_Checked(object sender, RoutedEventArgs e)
        {
            if (CSContent == null) return;
            CSContent.Content = SelectedDemoItem.CSBlock;
            CSContent.Visibility = Visibility.Visible;
            XAMLContent.Visibility = Visibility.Collapsed;
        }

        private void ViewOptionsPanel_Loaded(object sender, RoutedEventArgs e)
        {
            UpdateOptionsElementStyle((Panel)sender);
        }

        private void ExpandDescriptionButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            ExpandDescriptionButton_Click(null, null);
        }
    }
}
